﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PivotGridUsingFlatPivotTable.DataSource
{
	/*
	 * This is a really noddy mock implementation that in reality would
	 * be invoking a back-end service that knows how to provide an 
	 * aggregated pivot table type data structure based on various inputs
	 * (such as filters to slice through the data, and groupings for both
	 * axes. as well as the measures the user wants to see).
	 * 
	 * eg: 
	 *	Filter: 'Product Category' in ('A', 'B', 'C')
	 *	Measures: 'Cost Price', 'Quantity'
	 *	X-Axis: 'Measure' -> 'Currency'
	 *	Y-Axis: 'Department' -> 'Customer'
	 *	
	 *  This example will produce a grid of data categorised by two grouping values
	 *  on both axes.
	 *  
	 * My test data will represent something in this form, with two levels in each
	 * axis. My first level in each will have an imaginary two permutations,
	 * and the second level will have three. This means for both rows and columns
	 * I will have ((3 + 1(total)) * 2) + 1(total) = 9 cells of data, including 
	 * totals at each level.
	 * 
	 * We can then assume the server will SUM all values up to provide something 
	 * like this:
	 * 
	 */
	public class MockFlatPivotServerDataSource : IFlatPivotServerDataSource
	{
		public FlatPivotTable LoadData()
		{
			var pivotTable = new FlatPivotTable
			{
			    XAxis = CreateTestXAxis(),
			    YAxis = CreateTestYAxis(),
			    Cells = new []
 				{
					// Raw values at leaf nodes are simply 1-36, the rest of the 
					// values are all SUM values calulated from these.

					// A-Axis: T=TOTAL, M=MEASURE, C=CURRENCY

					//               T   M1 M1C1 M1C2 M1C3   M2 M2C1 M2C2 M2C3
					new object[] { 666, 306,  96, 102, 108, 360, 114, 120, 126 }, // TOTAL
					new object[] { 171,  72,  21,  24,  27,  99,  30,  33,  36 }, // DEPT-1; TOTAL
					new object[] {  21,   6,   1,   2,   3,  15,   4,   5,   6 }, // DEPT-1; CUST-1
					new object[] {  57,  24,   7,   8,   9,  33,  10,  11,  12 }, // DEPT-1; CUST-2
					new object[] {  93,  42,  13,  14,  15,  51,  16,  17,  18 }, // DEPT-1; CUST-3
					new object[] { 495, 234,  75,  78,  81, 261,  84,  87,  90 }, // DEPT-2; TOTAL
					new object[] { 129,  60,  19,  20,  21,  69,  22,  23,  24 }, // DEPT-2; CUST-1
					new object[] { 165,  78,  25,  26,  27,  87,  28,  29,  30 }, // DEPT-2; CUST-2
					new object[] { 201,  96,  31,  32,  33, 105,  34,  35,  36 }  // DEPT-2; CUST-3
				}
			};

			return pivotTable;
		}

		private static FlatPivotAxis CreateTestXAxis()
		{
			var measure1Ccy1Axis = new FlatPivotAxis
			{
			    Header = "CCY 1",
			    Level = 2, Position = 2, Width = 1
			};

			var measure1Ccy2Axis = new FlatPivotAxis
			{
				Header = "CCY 2",
				Level = 2, Position = 3, Width = 1
			};
			var measure1Ccy3Axis = new FlatPivotAxis
			{
				Header = "CCY 3",
				Level = 2, Position = 4, Width = 1
			};

			// Measure 1 consists of 3 currencies, 4 columns (including total and children)
			var measure1Axis = new FlatPivotAxis
			{
				Header = "Measure 1",
				Level = 1, Position = 1, Width = 4,
				Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "CCY 1", measure1Ccy1Axis }, 
					{ "CCY 2", measure1Ccy2Axis }, 
					{ "CCY 3", measure1Ccy3Axis }
				}
			};

			var measure2Ccy1Axis = new FlatPivotAxis
			{
				Header = "CCY 1",
				Level = 2, Position = 6, Width = 1
			};

			var measure2Ccy2Axis = new FlatPivotAxis
			{
				Header = "CCY 2",
				Level = 2, Position = 7, Width = 1
			};
			var measure2Ccy3Axis = new FlatPivotAxis
			{
				Header = "CCY 3",
				Level = 2, Position = 8, Width = 1
			};

			// Measure 2 consists of 3 currencies, 4 columns (including total and children)
			var measure2Axis = new FlatPivotAxis
			{
				Header = "Measure 2",
				Level = 1, Position = 5, Width = 4,
				Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "CCY 1", measure2Ccy1Axis }, 
					{ "CCY 2", measure2Ccy2Axis }, 
					{ "CCY 3", measure2Ccy3Axis }
				}
			};

			// Entire x-axis is two measures, each with 3 currencies, 9 columns (incl total and children)
			var xAxis = new FlatPivotAxis
			{
				Header = "All Data",
				Level = 0, Position = 0, Width = 9,				
				Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "Measure 1", measure1Axis },
					{ "Measure 2", measure2Axis }
				}
			};

			return xAxis;
		}

		private static FlatPivotAxis CreateTestYAxis()
		{
			var dept1Cust1Axis = new FlatPivotAxis
			{
				Header = "Cust 1",
				Level = 2, Position = 2, Width = 1
			};

			var dept1Cust2Axis = new FlatPivotAxis
			{
				Header = "Cust 2",
				Level = 2, Position = 3, Width = 1
			};
			var dept1Cust3Axis = new FlatPivotAxis
			{
				Header = "Cust 3",
				Level = 2, Position = 4, Width = 1
			};

			var dept1Axis = new FlatPivotAxis
			{
				Header = "Dept 1",
				Level = 1, Position = 1, Width = 4,
				Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "Cust 1", dept1Cust1Axis }, 
					{ "Cust 2", dept1Cust2Axis }, 
					{ "Cust 3", dept1Cust3Axis }
				}
			};

			var dept2Cust1Axis = new FlatPivotAxis
			{
				Header = "Cust 1",
				Level = 2, Position = 6, Width = 1
			};

			var dept2Cust2Axis = new FlatPivotAxis
			{
				Header = "Cust 2",
				Level = 2, Position = 7, Width = 1
			};
			var dept2Cust3Axis = new FlatPivotAxis
			{
				Header = "Cust 3",
				Level = 2, Position = 8, Width = 1
			};

			var dept2Axis = new FlatPivotAxis
			{
				Header = "Dept 2",
				Level = 1, Position = 5, Width = 4,
				Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "Cust 1", dept2Cust1Axis }, 
					{ "Cust 2", dept2Cust2Axis }, 
					{ "Cust 3", dept2Cust3Axis }
				}
			};

			var yAxis = new FlatPivotAxis
			{
				Header = "All Data",
				Level = 0, Position = 0, Width = 9,
				Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "Dept 1", dept1Axis },
					{ "Dept 2", dept2Axis }
				}
			};

			return yAxis;
		}

	}

    public class MockFlatPivotServerDataSource2 : IFlatPivotServerDataSource
    {
        public FlatPivotTable LoadData()
        {
            var pivotTable = new FlatPivotTable
            {
                XAxis = CreateTestXAxis(),
                YAxis = CreateTestYAxis(),
                Cells = new[]
 				{
					// Raw values at leaf nodes are simply 1-36, the rest of the 
					// values are all SUM values calulated from these.

					// A-Axis: T=TOTAL, M=MEASURE, C=CURRENCY

					//               T   M1 M1C1 M1C2 M1C3   M2 M2C1 M2C2 M2C3
					new object[] { 666, 306,  96, 102, 108, 360, 114, 120, 126 }, // TOTAL
					new object[] { 171,  72,  21,  24,  27,  99,  30,  33,  36 }, // DEPT-1; TOTAL
					new object[] {  21,   6,   1,   2,   3,  15,   4,   5,   6 }, // DEPT-1; CUST-1
					new object[] {  57,  24,   7,   8,   9,  33,  10,  11,  12 }, // DEPT-1; CUST-2
					new object[] {  93,  42,  13,  14,  15,  51,  16,  17,  18 }, // DEPT-1; CUST-3
					new object[] { 495, 234,  75,  78,  81, 261,  84,  87,  90 }, // DEPT-2; TOTAL
					new object[] { 129,  60,  19,  20,  21,  69,  22,  23,  24 }, // DEPT-2; CUST-1
					new object[] { 165,  78,  25,  26,  27,  87,  28,  29,  30 }, // DEPT-2; CUST-2
					new object[] { 201,  96,  31,  32,  33, 105,  34,  35,  36 }  // DEPT-2; CUST-3
				}
            };

            return pivotTable;
        }

        private static FlatPivotAxis CreateTestXAxis()
        {
            var measure1Ccy1Axis = new FlatPivotAxis
            {
                Header = "CCY2 1",
                Level = 2,
                Position = 2,
                Width = 1
            };

            var measure1Ccy2Axis = new FlatPivotAxis
            {
                Header = "CCY2 2",
                Level = 2,
                Position = 3,
                Width = 1
            };
            var measure1Ccy3Axis = new FlatPivotAxis
            {
                Header = "CCY2 3",
                Level = 2,
                Position = 4,
                Width = 1
            };

            // Measure 1 consists of 3 currencies, 4 columns (including total and children)
            var measure1Axis = new FlatPivotAxis
            {
                Header = "Measure2 1",
                Level = 1,
                Position = 1,
                Width = 4,
                Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "CCY2 1", measure1Ccy1Axis }, 
					{ "CCY2 2", measure1Ccy2Axis }, 
					{ "CCY2 3", measure1Ccy3Axis }
				}
            };

            var measure2Ccy1Axis = new FlatPivotAxis
            {
                Header = "CCY2 1",
                Level = 2,
                Position = 6,
                Width = 1
            };

            var measure2Ccy2Axis = new FlatPivotAxis
            {
                Header = "CCY2 2",
                Level = 2,
                Position = 7,
                Width = 1
            };
            var measure2Ccy3Axis = new FlatPivotAxis
            {
                Header = "CCY2 3",
                Level = 2,
                Position = 8,
                Width = 1
            };

            // Measure 2 consists of 3 currencies, 4 columns (including total and children)
            var measure2Axis = new FlatPivotAxis
            {
                Header = "Measure2 2",
                Level = 1,
                Position = 5,
                Width = 4,
                Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "CCY2 1", measure2Ccy1Axis }, 
					{ "CCY2 2", measure2Ccy2Axis }, 
					{ "CCY2 3", measure2Ccy3Axis }
				}
            };

            // Entire x-axis is two measures, each with 3 currencies, 9 columns (incl total and children)
            var xAxis = new FlatPivotAxis
            {
                Header = "All Data 2",
                Level = 0,
                Position = 0,
                Width = 9,
                Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "Measure2 1", measure1Axis },
					{ "Measure2 2", measure2Axis }
				}
            };

            return xAxis;
        }

        private static FlatPivotAxis CreateTestYAxis()
        {
            var dept1Cust1Axis = new FlatPivotAxis
            {
                Header = "Cust2 1",
                Level = 2,
                Position = 2,
                Width = 1
            };

            var dept1Cust2Axis = new FlatPivotAxis
            {
                Header = "Cust2 2",
                Level = 2,
                Position = 3,
                Width = 1
            };
            var dept1Cust3Axis = new FlatPivotAxis
            {
                Header = "Cust2 3",
                Level = 2,
                Position = 4,
                Width = 1
            };

            var dept1Axis = new FlatPivotAxis
            {
                Header = "Dept2 1",
                Level = 1,
                Position = 1,
                Width = 4,
                Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "Cust2 1", dept1Cust1Axis }, 
					{ "Cust2 2", dept1Cust2Axis }, 
					{ "Cust2 3", dept1Cust3Axis }
				}
            };

            var dept2Cust1Axis = new FlatPivotAxis
            {
                Header = "Cust2 1",
                Level = 2,
                Position = 6,
                Width = 1
            };

            var dept2Cust2Axis = new FlatPivotAxis
            {
                Header = "Cust2 2",
                Level = 2,
                Position = 7,
                Width = 1
            };
            var dept2Cust3Axis = new FlatPivotAxis
            {
                Header = "Cust2 3",
                Level = 2,
                Position = 8,
                Width = 1
            };

            var dept2Axis = new FlatPivotAxis
            {
                Header = "Dept2 2",
                Level = 1,
                Position = 5,
                Width = 4,
                Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "Cust2 1", dept2Cust1Axis }, 
					{ "Cust2 2", dept2Cust2Axis }, 
					{ "Cust2 3", dept2Cust3Axis }
				}
            };

            var yAxis = new FlatPivotAxis
            {
                Header = "All Data 2",
                Level = 0,
                Position = 0,
                Width = 9,
                Children = new Dictionary<object, FlatPivotAxis>
				{
				    { "Dept2 1", dept1Axis },
					{ "Dept2 2", dept2Axis }
				}
            };

            return yAxis;
        }

    }
}
